import lessVars from '@css/var.scss';
const HEADER_HEIGHT = lessVars.topNavBarHeight;

function throttle(func, delay) {
    var timer = null;
             
    return function() {
        var context = this;
        var args = arguments;
        
        if (!timer) {
            timer = setTimeout(function() {
                func.apply(context, args);
                timer = null;
            }, delay);
        }
    }
}

var isMobile = false;
if (process.browser) {
    isMobile = /iPhone|Android/i.test(window.navigator.userAgent.toLowerCase());
}

function Ceiling(obj) {
    this.init(obj);
};

Ceiling.prototype = {
    init(obj) {
        this.$settings = obj;
        this.$offsetPos = false;
        this.$con = this.$settings.con || document.querySelector('#__nuxt');
        this.$el = this.$settings.el;
        this.$type = this.$settings.type || 'top';
        this.$oWidth = 0;
        this.$oHeight = 0;
        this.$zIndex = 10;
        this.$zoom = this.$settings.zoom;
        this.$placeholder = null;
        this.$handler = obj.handler;
        this.$state = false;

        this.scrollHandler = throttle(function() {
            if (!this.$state) {
                this.autoPos();
            }

            if (this.$offsetPos !== false) {
                var handler = this.$typeScrollHandlerSwitchObj[this.$type];
    
                handler && handler.call(this);
            }
        }.bind(this), 1000 / 100);

        if (!isMobile) {
            this.addEListener();
        }

        var handler = this.$typeInitSwitchObj[this.$type];

        handler && handler.call(this);
    },
    $typeScrollHandlerSwitchObj: {
        top() {
            var scrollTop = this.$con.scrollTop;

            if (this.$zoom) {
                var zoomTop = this.getElementToPageTop(this.$zoom),
                    zoomHeihgt = this.$zoom.offsetHeight,
                    zooomBottomPos = zoomTop + zoomHeihgt,
                    delta = (zooomBottomPos - this.$oHeight) - scrollTop;

                if (scrollTop > zooomBottomPos - this.$oHeight) {
                    this.$el.style.top = delta + 'px';
                    this.createCeiling();
                    this.triggerEvent();

                    return;
                }
            }
        
            //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
            if (scrollTop > this.$offsetPos) {
                this.$el.style.top = HEADER_HEIGHT;
                this.createCeiling();
                this.triggerEvent();
            } else {
                this.clearCeiling();
                this.triggerEvent();
            }
        },
        bottom() {
            var scrollTop = this.$con.scrollTop,
                conHeight = this.$con.offsetHeight,
                elHeight = this.$settings.el.offsetHeight;
        
            //如果被卷曲的高度大于吸顶元素到顶端位置 的距离
            if (scrollTop + conHeight - elHeight > this.$offsetPos) {
                this.clearCeiling();
                this.triggerEvent();
            } else {
                this.$el.style.bottom = 0;
                this.createCeiling();
                this.triggerEvent();
            }
        },
    },
    $typeInitSwitchObj: {
        top() {
            
        },
        bottom() {
            setTimeout(() => {
                this.$el.style.position = 'fixed';
                this.$el.style.bottom = 0;
            }, 500);
        },
    },
    addEListener() {
        this.$con.addEventListener('scroll', this.scrollHandler.bind(this));
    },
    autoPos() {
        if (!this.$el) {
            return;
        }

        this.$oWidth = this.$el.offsetWidth;
        this.$oHeight = this.$el.offsetHeight;

        if (this.$type === 'top') {
            this.$offsetPos = this.getElementToPageTop(this.$el);
        } else if (this.$type === 'bottom') {
            this.$offsetPos = this.getElementToPageTop(this.$el) + this.$el.offsetHeight;
        }

        return this;
    },
    trimPos(num) {
        if (this.$offsetPos !== false && num) {
            this.$offsetPos += num;
        }
    },
    destroy() {
        this.$con.removeEventListener('scroll', this.scrollHandler.bind(this));

        try{
            this.clearCeiling();
        } catch(e) {
            // e
        }

        this.$settings = null;
        this.$offsetPos = null;
        this.$con = null;
        this.$el = null;
        this.$type = null;
        this.$oWidth = null;
        this.$oHeight = null;
        this.$zIndex = null;
        this.$zoom = null;
        this.$placeholder = null;
    },
    getElementToPageTop(el) {
        if(el.parentElement) {
            return this.getElementToPageTop(el.parentElement) + el.offsetTop
        }
        
        return el.offsetTop
    },
    createPlaceholder() {
        if (!this.$placeholder) {
            this.$placeholder = this.$el.cloneNode(true);

            this.$placeholder.style.opacity = 0;
            if (this.$el.nextSibling) {
                this.$el.parentElement.insertBefore(this.$placeholder, this.$el.nextSibling);
            } else {
                this.$el.parentElement.appendChild(this.$placeholder);
            }
        } else {
            this.$placeholder.style.display = '';
        }
    },
    hidePlaceholder() {
        if (this.$placeholder) {
            this.$placeholder.style.display = 'none';
        }
    },
    createCeiling() {
        this.createPlaceholder();

        this.$el.style.position = 'fixed';
        this.$el.style.width = this.$oWidth + 'px';
        this.$el.style.zIndex = this.$zIndex;

        this.$state = true;
    },
    clearCeiling() {
        this.hidePlaceholder();

        this.$el.style.position = '';
        this.$el.style.top = '';
        this.$el.style.bottom = '';
        this.$el.style.width = '';
        this.$el.style.zIndex = '';

        this.$state = false;
    },
    /**
     * 触发/解除吸顶时调用；
     * @param {Boolean} state 置顶状态
     */
    triggerEvent() {
        this.$handler && this.$handler(this.$state);
    },
};

export default Ceiling;